// -------------------------------------------------------------------------
//    @FileName         :    NFCProxyServerNet_ClientModule.cpp
//    @Author           :    LvSheng.Huang
//    @Date             :    2013-05-06
//    @Module           :    NFCProxyServerNet_ClientModule
//
// -------------------------------------------------------------------------

#include "NFCProxyServerToGameModule.h"
#include "NFProxyServerNet_ClientPlugin.h"
#include "NFComm/NFPluginModule/NFIClassModule.h"
#include "NFComm/NFMessageDefine/NFProtocolDefine.hpp"

bool NFCProxyServerToGameModule::Init()
{
    if (pPluginManager->IsLoadAllServer())
    {
        m_pNetClientModule = pPluginManager->CreateAloneModule<NFINetClientModule>();
        m_pNetClientModule->Awake();
        m_pNetClientModule->Init();
        m_pNetClientModule->AfterInit();
    }
    else
    {
        m_pNetClientModule = pPluginManager->FindModule<NFINetClientModule>();
    }
    m_pKernelModule = pPluginManager->FindModule<NFIKernelModule>();
    m_pProxyServerNet_ServerModule = pPluginManager->FindModule<NFIProxyServerNet_ServerModule>();
    m_pElementModule = pPluginManager->FindModule<NFIElementModule>();
    m_pLogModule = pPluginManager->FindModule<NFILogModule>();
    m_pClassModule = pPluginManager->FindModule<NFIClassModule>();

    return true;
}

bool NFCProxyServerToGameModule::Shut()
{
    //Final();
    //Clear();
    return true;
}

bool NFCProxyServerToGameModule::Execute()
{
    return true;
}

bool NFCProxyServerToGameModule::AfterInit()
{
    m_pNetClientModule->AddReceiveCallBack(NF_SERVER_TYPES::NF_ST_GAME, NFMsg::EGMI_ACK_ENTER_GAME, this, &NFCProxyServerToGameModule::OnAckEnterGame);
    m_pNetClientModule->AddReceiveCallBack(NF_SERVER_TYPES::NF_ST_GAME, NFMsg::EGMI_ACK_OFFLINE_NOTIFY, this, &NFCProxyServerToGameModule::OnAckOfflineNotify);
    m_pNetClientModule->AddReceiveCallBack(NF_SERVER_TYPES::NF_ST_GAME, this, &NFCProxyServerToGameModule::Transpond);

    m_pNetClientModule->AddEventCallBack(NF_SERVER_TYPES::NF_ST_GAME, this, &NFCProxyServerToGameModule::OnSocketGSEvent);
    m_pNetClientModule->ExpandBufferSize();

    NF_SHARE_PTR<NFIClass> xLogicClass = m_pClassModule->GetElement(NFrame::Server::ThisName());
    if (xLogicClass)
    {
        const std::vector<std::string>& strIdList = xLogicClass->GetIDList();
        for (int i = 0; i < (int)strIdList.size(); ++i)
        {
            const std::string& strId = strIdList[i];

            const int nServerType = m_pElementModule->GetPropertyInt(strId, NFrame::Server::Type());
            const int nServerID = m_pElementModule->GetPropertyInt(strId, NFrame::Server::ServerID());
            if (nServerType == NF_SERVER_TYPES::NF_ST_GAME)
            {
                const int nPort = m_pElementModule->GetPropertyInt(strId, NFrame::Server::Port());
                const int nMaxConnect = m_pElementModule->GetPropertyInt(strId, NFrame::Server::MaxOnline());
                const int nCpus = m_pElementModule->GetPropertyInt(strId, NFrame::Server::CpuCount());
                const std::string& strName = m_pElementModule->GetPropertyString(strId, NFrame::Server::Name());
                const std::string& strIP = m_pElementModule->GetPropertyString(strId, NFrame::Server::IP());

                ConnectData xServerData;

                xServerData.nServerID = nServerID;
                xServerData.eServerType = (NF_SERVER_TYPES)nServerType;
                xServerData.strIP = strIP;
                xServerData.nPort = nPort;
                xServerData.strName = strName;

                m_pNetClientModule->AddServer(xServerData);
            }
        }
    }

    return true;
}

bool NFCProxyServerToGameModule::Finalize()
{
    return true;
}

void NFCProxyServerToGameModule::AddServerInfoExt(const std::string& key, const std::string& value)
{
    m_mServerInfoExt[key] = value;
}

void NFCProxyServerToGameModule::OnSocketGSEvent(const int nSockIndex, const NF_NET_EVENT eEvent, NFINet* pNet)
{
    if (eEvent & NF_NET_EVENT_EOF)
    {
    }
    else if (eEvent & NF_NET_EVENT_ERROR)
    {
    }
    else if (eEvent & NF_NET_EVENT_TIMEOUT)
    {
    }
    else  if (eEvent == NF_NET_EVENT_CONNECTED)
    {
        m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFGUID(0, nSockIndex), "NF_NET_EVENT_CONNECTED", "connectioned success", __FUNCTION__, __LINE__);
        Register(pNet);
    }
}

void NFCProxyServerToGameModule::Register(NFINet* pNet)
{
    NF_SHARE_PTR<NFIClass> xLogicClass = m_pClassModule->GetElement(NFrame::Server::ThisName());
    if (xLogicClass)
    {
        const std::vector<std::string>& strIdList = xLogicClass->GetIDList();
        for (int i = 0; i < (int)strIdList.size(); ++i)
        {
            const std::string& strId = strIdList[i];

            const int nServerType = m_pElementModule->GetPropertyInt(strId, NFrame::Server::Type());
            const int nServerID = m_pElementModule->GetPropertyInt(strId, NFrame::Server::ServerID());
            if (nServerType == NF_SERVER_TYPES::NF_ST_PROXY && pPluginManager->GetAppID(NF_SERVER_TYPES::NF_ST_PROXY) == nServerID)
            {
                const int nPort = m_pElementModule->GetPropertyInt(strId, NFrame::Server::Port());
                const int nMaxConnect = m_pElementModule->GetPropertyInt(strId, NFrame::Server::MaxOnline());
                const int nCpus = m_pElementModule->GetPropertyInt(strId, NFrame::Server::CpuCount());
                const std::string& strName = m_pElementModule->GetPropertyString(strId, NFrame::Server::Name());
                const std::string& strIP = m_pElementModule->GetPropertyString(strId, NFrame::Server::IP());

                NFMsg::ServerInfoReportList xMsg;
                NFMsg::ServerInfoReport* pData = xMsg.add_server_list();

                pData->set_server_id(nServerID);
                pData->set_server_name(strName);
                pData->set_server_cur_count(0);
                pData->set_server_ip(strIP);
                pData->set_server_port(nPort);
                pData->set_server_max_online(nMaxConnect);
                pData->set_server_state(NFMsg::EST_NARMAL);
                pData->set_server_type(nServerType);
                NFMsg::ServerInfoExt pb_ServerInfoExt;
                pData->mutable_server_info_list_ext()->CopyFrom(pb_ServerInfoExt);

                NF_SHARE_PTR<ConnectData> pServerData = m_pNetClientModule->GetServerNetInfo(pNet);
                if (pServerData)
                {
                    int nTargetID = pServerData->nServerID;
                    m_pNetClientModule->SendToServerByPB(nTargetID, NFMsg::EGameMsgID::EGMI_PTG_PROXY_REGISTERED, xMsg);

                    // m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFGUID(0, pData->server_id()), pData->server_name(), "Register");
                }
            }
        }
    }
}

void NFCProxyServerToGameModule::OnAckEnterGame(const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
    NFGUID xClient;
    NFMsg::AckEnterGameServer xData;
    if (!NFINetModule::ReceivePB(nMsgID, msg, nLen, xData, xClient))
    {
        return;
    }

    const NFGUID& xPlayer = NFINetModule::PBToNF(xData.user_guid());

    m_pProxyServerNet_ServerModule->EnterGameSuccessEvent(xClient, xPlayer);
    m_pProxyServerNet_ServerModule->Transpond(nSockIndex, nMsgID, msg, nLen);

    m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, xPlayer, "Enter Game successed", "", __FUNCTION__, __LINE__);
}

void NFCProxyServerToGameModule::LogServerInfo(const std::string& strServerInfo)
{
    m_pLogModule->LogNormal(NFILogModule::NLL_INFO_NORMAL, NFGUID(), strServerInfo, "");
}

void NFCProxyServerToGameModule::OnAckOfflineNotify(const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
    m_pProxyServerNet_ServerModule->OnAckOfflineNotify(nSockIndex, nMsgID, msg, nLen);
}

void NFCProxyServerToGameModule::Transpond(const int nSockIndex, const int nMsgID, const char* msg, const uint32_t nLen)
{
    m_pProxyServerNet_ServerModule->Transpond(nSockIndex, nMsgID, msg, nLen);
}

void NFCProxyServerToGameModule::SendMsgToGame(const std::string& strHashKey, const int nMsgID, const std::string& strData)
{
    m_pNetClientModule->SendBySuit(NF_SERVER_TYPES::NF_ST_GAME, strHashKey, nMsgID, strData);
}

void NFCProxyServerToGameModule::SendMsgPBToGame(const std::string& strHashKey, const int nMsgID, const google::protobuf::Message& xData)
{
    m_pNetClientModule->SendSuitByPB(NF_SERVER_TYPES::NF_ST_GAME, strHashKey, nMsgID, xData);
}

void NFCProxyServerToGameModule::SendMsgToGameByServerID(const int nServerId, const int nMsgID, const  std::string& strData)
{
    m_pNetClientModule->SendByServerID(nServerId, nMsgID, strData);
}

NFMapEx<int, ConnectData>& NFCProxyServerToGameModule::GetServerList()
{
    return m_pNetClientModule->GetServerList();
}

NF_SHARE_PTR<ConnectData> NFCProxyServerToGameModule::GetServerNetInfo(const int nServerID)
{
    return m_pNetClientModule->GetServerNetInfo(nServerID);
}
